﻿﻿/* **********************************************************************************
 * Copyright (c) 2011 John Hughes
 *
 * j9Script is licenced under the Microsoft Reciprocal License (Ms-RL).
 *
 * Project Website: http://j9Script.codeplex.com/
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using J9Script.Internal;

namespace J9Script
{
    public class ScriptVariableCollection
    {
        Dictionary<string, IScriptObject> _items = new Dictionary<string, IScriptObject>(StringComparer.OrdinalIgnoreCase);

        public ScriptVariableCollection()
        {
        }

        public ScriptVariableCollection(ScriptVariableCollection items)
        {
            if (items != null)
                AddRange(items);
        }

        public void Set(string variablename, IScriptObject value)
        {
            ScriptVariableValue scriptvariable = new ScriptVariableValue(variablename, value);

            set(scriptvariable);
        }

        private void set(ScriptVariableValue scriptvariable)
        {
            if (_items.ContainsKey(scriptvariable.Name))
                _items[scriptvariable.Name] = scriptvariable.Value;
            else
                _items.Add(scriptvariable.Name, scriptvariable.Value);
        }

        public IScriptObject this[string variablename]
        {
            get { return (IScriptObject)_items[variablename]; }
            set
            {
                if (_items.ContainsKey(variablename))
                    _items[variablename] = value;
                else
                    _items.Add(variablename, value);
            }
        }

        public void AddRange(ScriptVariableCollection items)
        {
            foreach (string varName in items.Keys)
                Set(varName, items[varName]);
        }

        public int Count
        {
            get { return _items.Count; }
        }

        public bool Contains(string variablename)
        {
            return _items.ContainsKey(variablename);
        }

        public void Remove(string variablename)
        {
            _items.Remove(variablename);
        }

        public void Clear()
        {
            _items.Clear();
        }

        public ICollection Keys
        {
            get { return _items.Keys; }
        }
    }

    struct ScriptVariableValue
    {
        public string Name;
        public IScriptObject Value;

        internal ScriptVariableValue(Token token)
        {
            Name = token.IdentifierName;
            Value = token.ScriptObj;
        }

        public ScriptVariableValue(string name, IScriptObject value)
        {
            Name = name;
            Value = value;
        }

        public override string ToString()
        {
            return Value.TypeName + ", " + Value.ToPrimitiveString();
        }

        internal Token ToToken()
        {
            return new Token(Name, Value, TokenTypeEnum.EvaluatedExpression);
        }
        internal Token ToToken(ScriptPosition position, string tokenString)
        {
            return new Token(Name, Value, TokenTypeEnum.Identifier, position, tokenString);
        }

        public static ScriptVariableValue Empty
        {
            get
            {
                return new ScriptVariableValue(null, null);
            }
        }

        public bool IsEmpty
        {
            get
            {
                return Name == null && Value == null;
            }
        }
    }
}
